home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Aminet 31
/
Aminet 31 (1999)(Schatztruhe)[!][Jun 1999].iso
/
Aminet
/
dev
/
c
/
GAPLib.lha
/
GAPLib_Beta
/
wizards
/
Templates
/
report.c
< prev
next >
Wrap
C/C++ Source or Header
|
1999-04-22
|
6KB
|
287 lines
/*
* Report file generation utility code.
* See report.doc for more info.
*
* (C)1998-1999 Peter Bengtsson
*
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdarg.h>
#include <GAP.h>
#include "report.h"
static const char * const exts[REPFILES] = {
"avg",
"med",
"typ",
"max",
"min",
"dev"
};
static const char * const descs[REPFILES] = {
"Average",
"Median",
"TypeCount",
"Max",
"Min",
"StdDev"
};
struct Report *MakeReport(char *,struct TagItem *);
void DoReport(struct Report *,struct Population *,unsigned int);
void EndReport(struct Report *rs);
struct Report *MakeReport(char *basename,struct TagItem *TagList)
{
struct Report *rs;
char *buf=NULL;
int i;
Tag tag=TAG_DONE;
rs = malloc(sizeof(struct Report));
rs->flags=0;
rs->gencount=0;
for(i=0;i!=REPFILES;i++) {
rs->vbuffer[i]=NULL;
rs->cbuffer[i] = 0;
}
i=0;
if(rs!=0) {
if(TagList!=NULL) {
tag = TagList[0].ti_Tag;
}
while(tag!=TAG_DONE) {
switch(tag) {
case REP_Generations:
rs->gencount = TagList[i].ti_Data;
break;
case REP_Multipass:
rs->flags &= ~RFLG_MPASS;
if(TagList[i].ti_Data!=FALSE) {
rs->flags |= RFLG_MPASS;
}
break;
default:
fprintf(stderr,"MakeReport: Unrecognized tag 0x%08lx.\n",tag);
}
tag = TagList[++i].ti_Tag;
}
if((rs->flags&RFLG_MPASS) && rs->gencount==0) {
fprintf(stderr,"MakeReport: Multipass mode selected but number of generations undeclared.\nDisabling multipass mode.\n");
rs->flags &= ~RFLG_MPASS;
}
if(basename!=NULL) {
buf = malloc((strlen(basename)+8)*sizeof(char));
rs->basename = malloc((strlen(basename)+1)*sizeof(char));
strcpy(rs->basename,basename);
if(rs!=NULL && rs->basename!=NULL && buf!=NULL) {
for(i=0;i!=REPFILES;i++) {
sprintf(buf,"%s.%s",basename,exts[i]);
if((rs->files[i]=fopen(buf,"wb"))==NULL) {
while(--i>=0) {
fclose(rs->files[i]);
}
free(rs->basename);
free(rs);
rs = NULL;
fprintf(stderr,"MakeReport: Error opening files for writing.\n");
}
rs->used[i]=0;
fprintf(rs->files[i],"# Generation, %s\n",descs[i]);
}
} else {
if(rs!=NULL) {
if(rs->basename!=NULL) {
free(rs->basename);
}
free(rs);
rs = NULL;
}
fprintf(stderr,"MakeReport: No free store (malloc() failed).\n");
}
} else {
fprintf(stderr,"MakeReport: NULL basename.\n");
}
if(buf!=NULL) {
free(buf);
}
}
return(rs);
}
void EndReport(struct Report *rs)
{
int i,n;
char *buf=NULL;
if(rs!=NULL) {
if(rs->flags&RFLG_MPASS) {
for(i=0;i!=REPFILES;i++) {
if(rs->used[i]!=0) {
for(n=0;n!=rs->gencount;n++) {
fprintf(rs->files[i],"%d %f\n",n+1,rs->vbuffer[i][n]/((double)rs->cbuffer[i]));
}
}
}
}
buf=malloc((strlen(rs->basename)+8)*sizeof(char));
for(i=0;i!=REPFILES;i++) {
fclose(rs->files[i]); /* fclose does an fflush. */
if(rs->used[i]==0 && buf!=NULL) {
sprintf(buf,"%s.%s",rs->basename,exts[i]);
remove(buf);
}
}
if(rs->flags&RFLG_VBUF) {
for(i=0;i!=REPFILES;i++) {
if(rs->vbuffer[i]!=NULL) {
free(rs->vbuffer[i]);
}
}
}
free(rs->basename);
free(rs);
}
if(buf!=NULL) {
free(buf);
} else {
fprintf(stderr,"EndReport: No free store, continuing.\n");
}
}
void DoReport(struct Report *rs,struct Population *Pop,unsigned int flags)
{
int i,n,t;
struct Popstat *stat;
if(rs!=NULL && Pop!=NULL && flags!=0) {
stat = &Pop->Stat;
for(i=0;i!=REPFILES;i++) {
n = flags&(1<<i);
if(n!=0) {
rs->used[i]=1;
if(rs->flags&RFLG_MPASS) {
if(stat->Generation==1) {
rs->cbuffer[i]++;
}
if(stat->Generation>rs->gencount) {
fprintf(stderr,"DoReport: Generation overflow.\n");
} else {
if(rs->vbuffer[i]==NULL) {
if(rs->flags&RFLG_NOMEM) {
break;
}
rs->flags |= RFLG_VBUF;
rs->vbuffer[i] = malloc(rs->gencount*sizeof(double));
if(rs->vbuffer[i]==NULL) {
rs->flags |= RFLG_NOMEM;
fprintf(stderr,"DoReport: No free store for multipass buffer.\n(Failed to allocate %ld bytes.)\n",rs->gencount*sizeof(double));
break;
} else {
for(t=0;t!=rs->gencount;t++) {
rs->vbuffer[i][t] = 0.0;
}
}
}
switch(n) {
case AVERAGE:
rs->vbuffer[i][stat->Generation-1] += stat->AverageFitness;
break;
case MEDIAN:
rs->vbuffer[i][stat->Generation-1] += stat->MedianFitness;
break;
case TYPECOUNT:
rs->vbuffer[i][stat->Generation-1] += (double) stat->TypeCount;
break;
case MAX:
rs->vbuffer[i][stat->Generation-1] += stat->MaxFitness;
break;
case MIN:
rs->vbuffer[i][stat->Generation-1] += stat->MinFitness;
break;
case STDDEV:
rs->vbuffer[i][stat->Generation-1] += stat->StdDeviation;
break;
}
}
} else {
switch(n) {
case AVERAGE:
fprintf(rs->files[i],"%ld %f\n",stat->Generation,stat->AverageFitness);
break;
case MEDIAN:
fprintf(rs->files[i],"%ld %f\n",stat->Generation,stat->MedianFitness);
break;
case TYPECOUNT:
fprintf(rs->files[i],"%ld %ld\n",stat->Generation,stat->TypeCount);
break;
case MAX:
fprintf(rs->files[i],"%ld %f\n",stat->Generation,stat->MaxFitness);
break;
case MIN:
fprintf(rs->files[i],"%ld %f\n",stat->Generation,stat->MinFitness);
break;
case STDDEV:
fprintf(rs->files[i],"%ld %f\n",stat->Generation,stat->StdDeviation);
break;
}
}
}
}
}
}
struct Report *MakeReportT(char *basename,...)
{
va_list ap;
int i=0;
struct TagItem TagList[64]; /* Assumed big enough */
va_start(ap,basename);
while((TagList[i].ti_Tag = va_arg(ap,Tag)),TagList[i].ti_Tag != TAG_DONE && TagList[i].ti_Tag != TAG_MORE) {
TagList[i].ti_Data = va_arg(ap,IPTR);
i++;
}
if(TagList[i].ti_Tag == TAG_MORE) {
TagList[i].ti_Data = va_arg(ap,IPTR);
if(TagList[i].ti_Data == 0) {
fprintf(stderr,"MakeReportT: Illegal NULL value for TAG_MORE.\n");
TagList[i].ti_Tag = TAG_DONE;
}
}
va_end(ap);
return (MakeReport(basename,TagList));
}